package com.ali.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期时间工具类
 *
 * @author jack.wu
 * @version 1.0
 * @date 2020/8/19
 */
public class DateTimeUtils {

    /**
     * 年 例如:2018
     */
    public static final String YEAR = "yyyy";
    /**
     * 月 例如:12
     */
    public static final String MONTH = "MM";
    /**
     * 日 例如:28
     */
    public static final String DAY = "dd";
    /**
     * 小时 24小时制 例如:18
     */
    public static final String HOURS = "HH";
    /**
     * 小时 12小时制 例如:11
     */
    public static final String HOUR = "hh";
    /**
     * 分钟 例如：18
     */
    public static final String MINUTE = "mm";
    /**
     * 秒 例如：18
     */
    public static final String SECOND = "ss";
    /**
     * 日期 例如:2018-12-28
     */
    public static final String DATE = "yyyy-MM-dd";
    /**
     * 日期时间 例如:2018-12-28 10:00:00
     */
    public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    /**
     * 时间 例如:10:00:00
     */
    public static final String TIME = "HHmmss";
    /**
     * 时间 不包括秒 例如:10:00
     */
    public static final String TIME_WITHOUT_SECOND = "HH:mm";

    /**
     * 日期时间 不包括秒 例如:2018-12-28 10:00
     */
    public static final String DATE_TIME_WITHOUT_SECONDS = "yyyy-MM-dd HH:mm";

    /**
     * 获取当前年份字符串
     *
     * @return 当前年份字符串
     */
    public static String getYear() {
        SimpleDateFormat format = new SimpleDateFormat(YEAR);
        return format.format(new Date());
    }

    /**
     * 获取指定年份指定月份最后一天0时0分0秒
     *
     * @param year  年
     * @param month 月
     * @return 指定年份指定月份最后一天0时0分0秒
     */
    public static Date getYearMonthEnd(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定年份指定月份1号0时0分0秒
     *
     * @param year  年
     * @param month 月
     * @return 指定年份指定月份1号0时0分0秒
     */
    public static Date getYearMonthFirst(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, (month - 1), 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取本月1号0时0分0秒
     *
     * @return 本月1号0时0分0秒
     */
    public static Date getCurrentMonthFirst() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取本月最后一天0时0分0秒
     *
     * @return 本月最后一天0时0分0秒
     */
    public static Date getCurrentMonthEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定月份1号0时0分0秒
     *
     * @param month 月份
     * @return 指定月份1号0时0分0秒
     */
    public static Date getMonthFirst(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), (month - 1), 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定月份最后一天0时0分0秒
     *
     * @param month 月份
     * @return 指定月份最后一天0时0分0秒
     */
    public static Date getMonthEnd(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), month, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前月份字符串
     *
     * @return 当前月份字符串
     */
    public static String getMonth() {
        SimpleDateFormat format = new SimpleDateFormat(MONTH);
        return format.format(new Date());
    }

    /**
     * 获取两个日期相差天数
     *
     * @param fromDate 开始日期
     * @param toDate   结束日期
     * @return 相差天数(toDate - fromDate)
     */
    public static int daysBetween(Date fromDate, Date toDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(fromDate);
        long fromTime = calendar.getTimeInMillis();

        calendar.setTime(toDate);
        long toTime = calendar.getTimeInMillis();

        long betweenDays = (toTime - fromTime) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(betweenDays));
    }

    /**
     * 获取当前天数字符串
     *
     * @return 当前天数字符串
     */
    public static String getDay() {
        SimpleDateFormat format = new SimpleDateFormat(DAY);
        return format.format(new Date());
    }

    /**
     * 获取当前日期指定天数之后的日期
     *
     * @param num 指定的天数
     * @return 当前日期指定天数之后的日期
     */
    public static Date nextDay(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + num);
        return calendar.getTime();
    }

    /**
     * 获取现在时间小时（24小时制）
     *
     * @return 现在时间小时
     */
    public static String getHours() {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(HOURS);
        return formatter.format(date);
    }

    /**
     * 获取现在时间小时（12小时制）
     *
     * @return 现在时间小时
     */
    public static String getHour() {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(HOUR);
        return formatter.format(date);
    }

    /**
     * 获取现在时间分钟
     *
     * @return 现在时间分钟
     */
    public static String getMinute() {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(MINUTE);
        return formatter.format(date);
    }

    /**
     * 获取现在时间秒
     *
     * @return 现在时间秒
     */
    public static String getSecond() {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(SECOND);
        return formatter.format(date);
    }

    /**
     * 获取当前日期指定月数之后的日期
     *
     * @param num 指定月数
     * @return 当前日期指定月数之后的日期
     */
    public static Date nextMonth(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + num);
        return calendar.getTime();
    }

    /**
     * 获取当前日期指定年数之后的日期
     *
     * @param num 指定年数
     * @return 当前日期指定年数之后的日期
     */
    public static Date nextYear(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + num);
        return calendar.getTime();
    }

    /**
     * 获取与指定日期间隔给定天数的日期
     *
     * @param specifiedDay 制定日期
     * @param num          间隔天数
     * @return 指定日期间隔给定天数的日期
     * @throws Exception ParseException
     */
    public static String getSpecifiedDayAfter(String specifiedDay, int num) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat(DATE);
        Date specifiedDate = format.parse(specifiedDay);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(specifiedDate);

        int day = calendar.get(Calendar.DATE);
        calendar.set(Calendar.DATE, day + num);

        return format.format(calendar.getTime());
    }

    /**
     * 判断两个日期是否为同一天
     *
     * @param date        日期1
     * @param anotherDate 日期2
     * @return true相同 false不相同
     */
    public static boolean equalSameDay(Date date, Date anotherDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(DATE);
        String thisDate = formatter.format(date);
        String another = formatter.format(anotherDate);
        return thisDate.equals(another);
    }

    /**
     * 格式化日期
     *
     * @param date   日期
     * @param format 格式
     * @return 格式化日期
     */
    public static String formatString(Date date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * 格式化日期
     *
     * @param date 日期
     * @return 格式化日期
     */
    public static String format(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat(DATE);
        return formatter.format(date);
    }

    /**
     * 格式化日期
     *
     * @param date   日期
     * @param format 格式
     * @return 格式化日期
     * @throws Exception ParseException
     */
    public static Date formatDate(Date date, String format) throws Exception {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.parse(formatter.format(date));
    }

    /**
     * 格式化日期
     *
     * @param date 日期
     * @return 格式化日期
     * @throws Exception ParseException
     */
    public static Date parse(String date) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat(DATE);
        return format.parse(date);
    }
}
